package gps.monitor.jt809server.protocol;

import gps.monitor.jt809server.protocol.codec.IJt809Handler;
import gps.monitor.jt809server.protocol.codec.IJt809SubHandler;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;

/**
 * @author cyq
 * @date 2021/11/7
 * @desc talk is cheep,show me the code
 */
public final class Jt809ProtocolFactory {

    // TODO: 修改为可自定义配置
    //协议处理类的路径
    private static final String kProtocolClassPath = "gps.monitor.jt809server.protocol.codec";

    private static final HashMap<String, IJt809Handler> protocolHandlerMap = new HashMap<>();
    private static final HashMap<String, IJt809SubHandler> protocolSubHandlerMap = new HashMap<>();

    static {
        try {
            String packageDirName = kProtocolClassPath.replace('.', '/');
            Enumeration dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            while (dirs.hasMoreElements()) {
                URL url = (URL)dirs.nextElement();
                String protocol = url.getProtocol();
                if ("file".equals(protocol)) {
                    String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                    findProtocolClass(filePath);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void findProtocolClass(String filePath) {
        File dir = new File(filePath);
        if (dir.exists() && dir.isDirectory()) {
            File[] dirfiles = dir.listFiles(new FileFilter() {
                public boolean accept(File file) {
                    return file.isDirectory() || file.getName().endsWith(".class");
                }
            });
            if (dirfiles == null) return;
            int size = dirfiles.length;
            for(int i = 0; i < size; ++i) {
                File file = dirfiles[i];
                if (file.isDirectory()) {
                    findProtocolClass(file.getAbsolutePath());
                } else {
                    String className = file.getName().substring(0, file.getName().length() - 6);
                    if (className.startsWith("Jt809Handler")) {
                        String protocol = className.replace("Jt809Handler","");
                        try {
                            Class<IJt809Handler> clazz = (Class<IJt809Handler>) Thread.currentThread().getContextClassLoader().loadClass(kProtocolClassPath + '.' + className);
                            try {
                                IJt809Handler instance = clazz.newInstance();
                                protocolHandlerMap.put(protocol, instance);
                            } catch (InstantiationException | IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    }else if (className.startsWith("Jt809SubHandler")) {
                        String protocol = className.replace("Jt809SubHandler","");
                        try {
                            Class<IJt809SubHandler> clazz = (Class<IJt809SubHandler>) Thread.currentThread().getContextClassLoader().loadClass(kProtocolClassPath + '.' + className);
                            try {
                                IJt809SubHandler instance = clazz.newInstance();
                                protocolSubHandlerMap.put(protocol, instance);
                            } catch (InstantiationException | IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    /**
     * 需要无参构造方法
     * @param hexUpperMsgid msgid 的16进制字符串 大写
     * @return 返回一个 protocol 空实体
     */
    public static IJt809Handler getJt809Handler(String hexUpperMsgid) {
        return protocolHandlerMap.get(hexUpperMsgid);
    }

    public static IJt809SubHandler getJt809SubHandler(String hexUpperSubMsgid) {
        return protocolSubHandlerMap.get(hexUpperSubMsgid);
    }

}
